/**
 * Looker  新闻整合系统
 * Author  :solosky <solosky772@qq.com>
 * File    :Data.js
 * Date    :August 5, 2009
 * License : Apache License 2.0 
 */

/**
 *  数据管理
 *  定义了从网络获取数据的机制
 *  是对jqueryAjax的封装，管理同时获取数据的连接，防止大量的请求同时提交到服务器
 */
  
  
  /**
   * 请求对象
   * 这个对象只是简单的保存请求的参数，不做任何处理
   * 参数类型中包含了ajax所有请求设置，这里新增了一个requestType设置 保存了请求的类型
   */
  var Request = function(options){
	  	this.xtype   = "Request";		 //类型名
		this.requestType  = "server";    //请求的类型
									 //server:一般的服务器请求，
									 //proxy:代理请求，ajax不能跨域，请求交给服务器去完成
									 //script:可以使用脚本来实现跨域请求	
		this.requestID  = Config.Data.RequestID++;
  		this.options = {
		};
		
		this.toString = function(){
			var str = ["[",this.requestID," - ",this.xtype," - ",this.requestType," - ",this.options.url,"]"];
			return str.join("");
		}
		
		//复制参数
		$.extend(this.options,options);
  };
  
  
  /**
   * 普通服务器请求对象
   */
   var ServerRequest = function(options){
	    Request.apply(this, arguments);
		
		this.xtype = "ServerRequest";
		this.requestType = "server";
   };
   //继承
   $.extend(ServerRequest,Request);
   
   
   /**
   * 代理服务器请求对象
   */
   var ProxyRequest = function(options){
	    Request.apply(this, arguments);
		
		this.xtype = "ProxyRequest";
		this.requestType = "proxy";
		//需要修改请求参数，把请求的地址换成定义的服务器代理地址,然后把源地址作为参数传递
		if(!this.options.data)
			this.options.data = {};
		this.options.data.url = this.options.url;
		this.options.data.method = this.options.type;
		this.options.url = Config.Data.ProxyURL;
	
		this.toString = function(){
			var str = ["[",this.requestID," - ",this.xtype," - ",this.requestType," - ",this.options.data.url,"]"];
			return str.join("");
		}
   };
    //继承
   $.extend(ProxyRequest,Request);
   
   
  /**
   * 脚本请求对象
   */
   var ScriptRequest = function(options){
	    Request.apply(this, arguments);
		
		this.xtype = "ScriptRequest";
		this.requestType = "script";
		//TODO 完善
   };
   
    //继承
   $.extend(ScriptRequest,Request);
   
   
   /**
    * 请求处理器
	* 发起请求，并完成回调
	*/
	var RequestProcessor = function(req){
		
		this.xType   = "RequestProcessor";					//类名
		this.request = req;									//请求对象
		this.originalSuccess = this.request.options.success;//原来的成功回调函数
		this.originalError   = this.request.options.error; 	//原来失败的回调函数
		
		//处理请求
		this.process = function(){
			var self = this;    //闭包啦。。
			//分别定义成功和失败的回调函数
			var proxySuccess = function(data){
				self.success(data);
			};
			var proxyError   = function(data){			
				self.error(data);
			};	
			//替换掉原来定义的请求
			this.request.options.success = proxySuccess;
			this.request.options.error   = proxyError;	
			
			Logger.debug("RequestProcessor 发起请求 "+this.request.toString());
			$.ajax(this.request.options);
			
		};
		//成功回调函数
		this.success = function(data){
			Logger.info("RequestProcessor 请求成功 "+this.request.toString());		
			RequestManager.finishedRequest(true);
			
			if(typeof this.originalSuccess !="undefined")
				this.originalSuccess(data);		//回调定义的成功回调函数
				
			RequestManager.requestLoop();		//完成后发起下一次请求
			
		};	
		//失败回调函数
		this.error = function(data){			
			Logger.warn("RequestProcessor 请求失败 "+this.request.toString());			
			 RequestManager.finishedRequest(false);
			 
			if(typeof this.originalError !="undefined")
				this.originalError(data);				//回调定义的错误处理函数回调函数
			
			RequestManager.requestLoop();				//完成后发起下一次请求
		};
	};
   
   
  /**
   * 请求管理器
   * 全局对象所有的请求都由管理器发起，用户代码只是建立了个请求信息，并没有开始具体的请求
   * 请求管理管理了所有的请求，用了一个队列来保存需要完成的请求，可以定义最多同时发起请求的数量，防止服务器过载
   */
   var RequestManager = {
	   
	   options : { 						//配置
		   MaxLiveRequest : 1			//最多同时进行的请求数目
	   },
	   ReadyRequestQueue  : new Array(),	//等待完成的请求队列
	   successRquestCount : 0,				//已经成功进行的请求数目
	   failRequestConnt	  : 0 , 			//失败的请求数目
	   activeRequestCount : 0,				//正在进行的请求数目
	   
	   //添加一个请求
	   addRequest : function(request){
			this.ReadyRequestQueue.push(request);   
			this.requestLoop();
	   },
	   
	   
	   //请求循环，如果有请求添加或者完成就会回调这个函数
	   requestLoop : function(){
		 //检查当前正在进行的请求是否小于配置的最大请求，如果是，发起下一个请求
		 if( this.activeRequestCount< this.options.MaxLiveRequest && this.ReadyRequestQueue.length>0 ){
			var readyRequest = this.ReadyRequestQueue.pop();
			this.activeRequestCount++;
			this.processRequest(readyRequest);
			
		 }
	   },
	   
	   //正式向服务器发起请求
	   processRequest : function(request){
		   var processor = new RequestProcessor(request);
		   processor.process();
	   },
	   //完成请求，减小正在进行的请求数目
	   finishedRequest : function(result){
		   result ? this.successRequestCount++ :  this.failRequestCount++;
		   this.activeRequestCount--;
	   }
	 
   };
   